Cross-Origin Resource Sharing
Cross-Origin Resource Sharing
跨來源資源共用
https://www.youtube.com/watch?v=4KHiSt0oLJ0
同源政策
Same-Origin Policy
在瀏覽器端
在同源的情況下,存取不會收到限制
1. 相同的通訊協定
2. 相同的網域
跨來源請求
Cross-Origin Http Request
非同源的請求,就會產生跨來源請求,必須遵守CORS規範
Access to fetch at *** from origin *** has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
CORS
伺服器會明確告知瀏覽器允許何種請求,只有受允許的會被發送
簡單跨來源請求
1. HTTP GET/POST/HEAD
2. 自訂request header為
Accept
Accept-Language
Content-Language/Content-Type
值為application/x-www-form-urlencoded、multipart/form-data或text/plain
Origin
瀏覽器發送跨來源請求時,會附帶的header,表示請求來源
包含通訊協定、網域和通訊埠
Access-Control-Allow-Origin
伺服器端收到跨來源請求時,會依據Origin的值決定是否允許
允許跨來源請求時,會在response中加上此header作為授權
例如
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Origin: *
允許所有來源
瀏覽器收到response後,會檢查Origin的值是否和此hedaer相符
如果不符時,即使有成功收到回應,仍然會判斷為請求失敗
Access-Control-Expose-Headers
預設可存取的簡單response header有
Cache-Control
Content-Language
Content-Type
Expires
Last-Modified
Pragma
此header用於讓JavaScript可存取其他header用
一般跨來源請求
除了簡單請求外的情況,瀏覽器會先發送一個Preflight Request
Preflight Request
預先確認請求是否符合CORS規範
HTTP OPTIONS
包含header
Origin
Access-Control-Request-Method
跨來源請求的HTTP方法
Access-Control-Request-Headers
跨來源請求的request header
Preflight Response
伺服器端會回應200、空body和以下header
Access-Control-Allow-Methods
允許的HTTP方法
Access-Control-Allow-Headers
允許的request header
Access-Control-Allow-Origin
允許的請求來源
瀏覽器端如果要取用cookie,也需要明確表示
Fetch
credentials: 'include'
XMLHttpRequest
withCredentials = true
伺服器端的response也需要附帶Access-Control-Allow-Credentials,瀏覽器才會存入值
基於資訊安全上的理由,此header值不可為*
在瀏覽器和請求目標網址之間插一個代理伺服器協助請求,藉此解決CORS問題
code:javascript
// use cors-anywhere to fetch api data
// origin api url
// fetch api url by cors-anywhere
axios.get(${cors}${url}).then(
(response) => {
const msg = response.data;
document.body.innerHTML = JSON.stringify(msg);
},
(error) => {}
);